/*

Gamebots UT Copyright (c) 2002, Andrew N. Marshal, Gal Kaminka
Gamebots UT 2003/2004 port Copyright (c) 2005
       Joe Manojlovich, Tim Garwood, Jessica Bayliss
Gamebots Pogamut derivation Copyright (c) 2007, Michal Bida
	- derived mainly from 2002 Marshal, Kaminka version

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

   * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This software must also be in compliance with the Epic Games Inc. license for mods which states the following: "Your mods must be distributed solely for free, period. Neither you, nor any other person or party, may sell them to anyone, commercially exploit them in any way, or charge anyone for receiving or using them without prior written consent of Epic Games Inc. You may exchange them at no charge among other end-users and distribute them to others over the Internet, on magazine cover disks, or otherwise for free." Please see http://www.epicgames.com/ut2k4_eula.html for more information.

*/


// Interaction class creates custom GB Hud and handles keyInput
// The reachability grid is drawn here
class GBHUDInteraction extends Interaction;

//Holds our GBHUD
var GBHUD MyHUD;
var config bool bDrawNavPointsGrid;
var bool bNavPointsGridDrawn;

var private bool bPressedAlt;

//Called as the first function. Prepare everything here.
event Initialized()
{
	bNavPointsGridDrawn = false;
	InitHud();
	if (bDrawNavPointsGrid)
	{
		DrawNavPointsGrid();
	}
}

//Called when the server will change the map - we will have to destroy everything
event NotifyLevelChange()
{
	ViewportOwner.Actor.ClearStayingDebugLines();
	bNavPointsGridDrawn = false;

	MyHUD.Destroy();
    if (ViewportOwner.Actor.isA('GBxPlayer'))
    {
		GBxPlayer(ViewportOwner.Actor).GBHUD = None;
	}
    ViewportOwner.InteractionMaster.RemoveInteraction(self);
	/*
	InitHud();
	if (bDrawNavPointsGrid)
	{
		DrawNavPointsGrid();
	}
	*/
}

//Here we will spawn our GBHUD and set it also to the Player
function InitHud()
{
    MyHUD = ViewportOwner.Actor.Spawn(class'BotAPI.GBHud', ViewportOwner.Actor);

    if (ViewportOwner.Actor.isA('GBxPlayer'))
    {
		GBxPlayer(ViewportOwner.Actor).GBHUD = MyHUD;
		//GBxPlayer(ViewportOwner.Actor).GBHUDInter = self;
	}
}

function DoTest()
{
	local NavigationPoint N;
	local int i, PathListLength, red, green, blue;
	local int bPlayersOnly, bForced, bProscribed, bLadder, bSpecial, bDoor, bJump, bSwim, bFly, bWalk;
	local vector resVect, resNormal;

	ViewportOwner.Actor.ClearStayingDebugLines();

	for ( N=ViewportOwner.Actor.Level.NavigationPointList; N!=None; N=N.NextNavigationPoint )
	{
    	if (N.IsA('JumpDest'))
    	{
    		for (i=0; i < JumpDest(N).NumUpstreamPaths; i++)
			{

            	GetFlags(JumpDest(N).UpstreamPaths[i].reachFlags, bPlayersOnly, bForced, bProscribed, bLadder, bSpecial, bDoor, bJump, bSwim, bFly, bWalk);

				//Dark green
    	        red = 0;
        	    green = 100;
            	blue = 0;

				if ( (bFly == 1) || (bProscribed == 1) || (bPlayersOnly == 1) )
				{
					//Red
					red = 255;
					green = 0;
					blue = 0;
				}
				else if ((bJump == 1) && (bSpecial == 1))
            	{
            		//White
					red = 255;
					green = 255;
					blue = 255;
				}
				else if ( bSpecial == 1 )
				{
					//Blue
					red = 0;
					green = 0;
					blue = 255;
				}
				else if (bJump == 1)
				{
					//Yellow
					red = 255;
					green = 255;
					blue = 0;
				}
				else if ( bDoor == 1 || bLadder == 1 || bSwim == 1 )
				{
					//Black
					red = 0;
					green = 0;
					blue = 0;
				}

				ViewportOwner.Actor.DrawStayingDebugLine(N.Location,JumpDest(N).UpstreamPaths[i].Start.Location,red,green,blue);


				resNormal = Normal((N.Location - JumpDest(N).UpstreamPaths[i].Start.Location) cross vect(0, 0, 1));
				resVect = N.Location - (Normal(N.Location - JumpDest(N).UpstreamPaths[i].Start.Location) * 14);

				ViewportOwner.Actor.DrawStayingDebugLine(resVect + resNormal * 5,N.Location,red,green,blue);
				ViewportOwner.Actor.DrawStayingDebugLine(resVect - resNormal * 5,N.Location,red,green,blue);
				ViewportOwner.Actor.DrawStayingDebugLine(resVect + resNormal * 5,resVect - resNormal * 5,red, green, blue);

			}

		}
	}

}

//Here we will draw the navigation points GRID in the game by DrawStayingDebugLine function
function DrawNavPointsGrid()
{
	local NavigationPoint N;
	local int i, PathListLength, red, green, blue;
	local int bPlayersOnly, bForced, bProscribed, bLadder, bSpecial, bDoor, bJump, bSwim, bFly, bWalk;
	local vector resVect, resNormal;

	for ( N=ViewportOwner.Actor.Level.NavigationPointList; N!=None; N=N.NextNavigationPoint )
	{
		i = 0;
		PathListLength = N.PathList.Length;
		for (i=0; i < PathListLength; i++)
		{
			//First we will get the flags of this line between two NavPoints
            GetFlags(N.PathList[i].reachFlags, bPlayersOnly, bForced, bProscribed, bLadder, bSpecial, bDoor, bJump, bSwim, bFly, bWalk);

			//Dark green
            red = 0;
            green = 100;
            blue = 0;

			//Here we will design what color we will use - hierarchical
			if ( (bFly == 1) || (bProscribed == 1) || (bPlayersOnly == 1) )
			{
				//Red
				red = 255;
				green = 0;
				blue = 0;
			}
			else if ((bJump == 1) && (bSpecial == 1))
            {
            	//White
				red = 255;
				green = 255;
				blue = 255;
			}
			else if ( bSpecial == 1 )
			{
				//Blue
				red = 0;
				green = 0;
				blue = 255;
			}
			else if (bJump == 1)
			{
				//Yellow
				red = 255;
				green = 255;
				blue = 0;
			}
			else if ( bDoor == 1 || bLadder == 1 || bSwim == 1 )
			{
				//Black
				red = 0;
				green = 0;
				blue = 0;
			}

			//Draw the line between two NavPoints
			ViewportOwner.Actor.DrawStayingDebugLine(N.Location,N.PathList[i].End.Location,red,green,blue);

			//We need this, so we can draw the arrow at the end of the line correctly
			resNormal = Normal((N.PathList[i].End.Location - N.Location) cross vect(0, 0, 1));
			resVect = N.PathList[i].End.Location - (Normal(N.PathList[i].End.Location - N.Location) * 14);

			//Right line of the arrow
			ViewportOwner.Actor.DrawStayingDebugLine(resVect + resNormal * 5,N.PathList[i].End.Location,red,green,blue);
			//Left line of the arrow
			ViewportOwner.Actor.DrawStayingDebugLine(resVect - resNormal * 5,N.PathList[i].End.Location,red,green,blue);
			//Line connecting the ends of our arrow lines
			ViewportOwner.Actor.DrawStayingDebugLine(resVect + resNormal * 5,resVect - resNormal * 5,red, green, blue);
			//GBHUD(MyHUD).DrawLine(N.Location,N.PathList[i].End.Location);
		}

	}
	bNavPointsGridDrawn = true;

}

//Will return the bools from supported flag int
function GetFlags(int flag, out int bPlayerOnly, out int bForced,
out int bProscribed, out int bLadder, out int bSpecial,
out int bDoor, out int bJump, out int bSwim, out int bFly, out int bWalk)
{
	bPlayerOnly = 0;
	bForced = 0;
	bProscribed = 0;
	bLadder = 0;
	bSpecial = 0;
	bDoor = 0;
	bJump = 0;
	bSwim = 0;
	bFly = 0;
	bWalk = 0;

	if ( flag >= 512 )
	{
		flag -= 512;
		bPlayerOnly = 1;
	}
    if ( flag >= 256 )
	{
		flag -= 256;
		//It is FORCED path
		bForced = 1;
	}
	if ( flag >= 128)
	{
		flag -= 128;
		bProscribed = 1;
	}
	if ( flag >= 64)
	{
		flag -= 64;
		bLadder = 1;
	}
	if ( flag >= 32)
	{
		flag -= 32;
		bSpecial = 1;
	}
	if ( flag >= 16)
	{
		flag -= 16;
		bDoor = 1;
	}
	if ( flag >= 8)
	{
		flag -= 8;
		bJump = 1;
	}
	if ( flag >= 4)
	{
		flag -= 4;
		bSwim = 1;
	}
	if ( flag >= 2)
	{
		flag -= 2;
		bFly = 1;
	}
	if ( flag >= 1 )
	{
		flag -= 1;
		bWalk = 1;
	}

}

//Here we handle our GB key presses
function bool KeyEvent(EInputKey InputKey, EInputAction InputAction, FLOAT Delta )
{

	if (InputKey == IK_Alt)
    	if (InputAction == IST_Press)
			bPressedAlt = True;
    	else if (InputAction == IST_Release)
			bPressedAlt = False;

	 if (bPressedAlt && InputAction == IST_Press)
	 {
		switch (InputKey)
		{
			case IK_B:
				MyHUD.bDisplayHealthBar = !MyHUD.bDisplayHealthBar;
			break;
		    case IK_G:
				if( bNavPointsGridDrawn )
				{
					ViewportOwner.Actor.ClearStayingDebugLines();
					bNavPointsGridDrawn = false;
				}
				else
					DrawNavPointsGrid();
			break;
		    case IK_H:
		    	MyHUD.bDisplayHelp = !MyHUD.bDisplayHelp;
			break;
			case IK_I:
				MyHUD.bDisplayInformation = !MyHUD.bDisplayInformation;
			break;
			case IK_L:
				MyHUD.bDisplayPlayerList = !MyHUD.bDisplayPlayerList;
			break;
			case IK_M:
				MyHUD.bDisplayMyLocation = !MyHUD.bDisplayMyLocation;
			break;
			case IK_N:
				MyHUD.bDrawNavPointsNames = !MyHUD.bDrawNavPointsNames;
			break;
			case IK_P:
				MyHUD.DisplayPlayerPositions += 1;
				if (MyHUD.DisplayPlayerPositions > 2)
					MyHUD.DisplayPlayerPositions = 0;
			break;
			case IK_R:
				MyHUD.bDisplayRoute = !MyHUD.bDisplayRoute;
			break;
		    case IK_T:
		    	DoTest();
			break;
			case IK_U:
				MyHUD.bDisplayTextBubble = !MyHUD.bDisplayTextBubble;
			break;
    		case IK_LeftBracket :
				if (MyHUD.NavPointBeaconDrawDistance < 4000)
					MyHUD.NavPointBeaconDrawDistance += 100;
			break;
		    case IK_RightBracket:
				if (MyHUD.NavPointBeaconDrawDistance > 100)
					MyHUD.NavPointBeaconDrawDistance -= 100;
			break;
		}
		return true; //This means that this key combinations won't be parsed by other KeyEvents
	}
    return super.KeyEvent(InputKey, InputAction, Delta );
}

/* This function is called by engine, we will forward this to our HUD, so we can
	draw information on it.
*/
function PostRender( canvas Canvas )
{
	if (MyHUD != none)
    	MyHUD.PostRender(Canvas);
}

defaultproperties
{
     bVisible=True
}
